package net.sf.sbv.helpers;


import net.sf.sbv.modals.SmsFileDetail;
import net.sf.sbv.modals.Message;
import net.sf.sbv.modals.Contact;
import java.io.File;
import java.math.BigInteger;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Pratik
 */
public class Utils {

    public static SmsFileDetail parseAndGetSmsFileDetails(File fXmlFile) throws Exception {
        SmsFileDetail smsDetail = null;

        // Depreciated object. To be replaced with Hashmap?
        Map<Contact, Contact> contactTable = new LinkedHashMap<Contact, Contact>();

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(fXmlFile);
        doc.getDocumentElement().normalize();

        Element docEle = doc.getDocumentElement();

        // Get a nodelist of elements in the XML file
        NodeList nl = docEle.getElementsByTagName("sms");
        if (nl != null && nl.getLength() > 0) {
            smsDetail = new SmsFileDetail();
            smsDetail.setNumberOfMessages(nl.getLength());

            for (int i = 0; i < nl.getLength(); i++) {
                //Get the message element
                Element msgElement = (Element) nl.item(i);

                // Get the message object
                Message msg = getText(msgElement);

                // Begin code to add/update contact in Hashtable
                Contact newContact = new Contact(msgElement.getAttribute("contact_name"), msgElement.getAttribute("address"));

                Contact alreadySavedContact = contactTable.get(newContact);
                if (alreadySavedContact != null) {
                    //add the message to the existing one
                    alreadySavedContact.addMessage(msg);
                } else {
                    //add the new contact in the map
                    newContact.addMessage(msg);
                    contactTable.put(newContact, newContact);
                }
                // End section
            }

            smsDetail.setSmsData(contactTable);
        }

        return smsDetail;
    }

    private static Message getText(Element empEl) {
        BigInteger date = new BigInteger(empEl.getAttribute("date"));
        String body = empEl.getAttribute("body");
        int type = Integer.parseInt(empEl.getAttribute("type"));

        Message msg = new Message(date, body, type);

        return msg;
    }

    public static SmsFileDetail searchKeyword(String keyword, SmsFileDetail universeData) {
        if(keyword == null || universeData == null) {
            return null;
        }

        if(keyword.isEmpty()) {
            return universeData;
        }

        //else search for data
        SmsFileDetail searchResult = new SmsFileDetail();
        keyword = keyword.toLowerCase();

        int messageCount = 0;
        //iterate through all the contacts in the universe
        for(Map.Entry<Contact, Contact> entry : universeData.getSmsData().entrySet()) {
            Contact contact = entry.getValue();

            if(contact.toString().toLowerCase().contains(keyword)) {
                //the contact itself matches the keyword, put this entry
                searchResult.addContact(contact, contact);

                //increase count of messages
                messageCount += contact.getMessages().size();
            } else {//search in the messages
                //create a new contact and put the results in it, if matched
                Contact newContact = new Contact(contact.getName(), contact.getNumber());

                //iterate through all the messages and search for the keyword, if found put it in the new contact
                for(Message msg : contact.getMessages()) {
                    if(msg.getMessageText().toLowerCase().contains(keyword)) {
                        newContact.addMessage(msg);
                        messageCount++;
                    }
                }

                //put this contact in the search result if it is not empty
                if(!newContact.getMessages().isEmpty()) {
                    searchResult.addContact(newContact, newContact);
                }
            }

            //now set the number of messages filtered through this search
            searchResult.setNumberOfMessages(messageCount);
        }

        return searchResult;
    }
}
